module libeventd.Dns ;

import
	libeventd.Types;

enum{
	DNS_ERR_NONE =0,
	DNS_ERR_FORMAT =1,
	DNS_ERR_SERVERFAILED =2,
	DNS_ERR_NOTEXIST =3,
	DNS_ERR_NOTIMPL =4,
	DNS_ERR_REFUSED =5,
	DNS_ERR_TRUNCATED =65,
	DNS_ERR_UNKNOWN =66,
	DNS_ERR_TIMEOUT =67,
	DNS_ERR_SHUTDOWN =68,
	DNS_ERR_CANCEL =69,

	DNS_IPv4_A =1,
	DNS_PTR =2,
	DNS_IPv6_AAAA =3,

	DNS_QUERY_NO_SEARCH =1,

	DNS_OPTION_SEARCH =1,
	DNS_OPTION_NAMESERVERS =2,
	DNS_OPTION_MISC =4,
	DNS_OPTION_HOSTSFILE =8,
	DNS_OPTIONS_ALL =15,
}
enum {
	EVDNS_ANSWER_SECTION =0,
	EVDNS_AUTHORITY_SECTION =1,
	EVDNS_ADDITIONAL_SECTION =2,

	EVDNS_TYPE_A	   =1,
	EVDNS_TYPE_NS	   =2,
	EVDNS_TYPE_CNAME   =5,
	EVDNS_TYPE_SOA	  = 6,
	EVDNS_TYPE_PTR	  =12,
	EVDNS_TYPE_MX	  =15,
	EVDNS_TYPE_TXT	  =16,
	EVDNS_TYPE_AAAA	  =28,

	EVDNS_QTYPE_AXFR =252,
	EVDNS_QTYPE_ALL	= 255,

	EVDNS_CLASS_INET   =1,
	EVDNS_FLAGS_AA	=0x400,
	EVDNS_FLAGS_RD	=0x080,
}

const DNS_NO_SEARCH  = 1;

extern(C):

struct evdns_getaddrinfo_request;
struct in_addr;

alias void  function(ev_int result, char type, ev_int count, ev_int ttl, void *addresses, void *arg) evdns_callback_type;
alias void function(ev_int is_warning, char *msg) evdns_debug_log_fn_type;
alias void function(evdns_server_request *, void *) evdns_request_callback_fn_type;
alias void function(int result, evutil_addrinfo *res, void *arg) evdns_getaddrinfo_cb;

evdns_base * evdns_base_new( event_base *event_base, ev_int initialize_nameservers);
void evdns_base_free( evdns_base *base, ev_int fail_requests);
char *evdns_err_to_string(ev_int err);
ev_int evdns_base_nameserver_add( evdns_base *base, ev_uint address);
ev_int evdns_base_count_nameservers( evdns_base *base);
ev_int evdns_base_clear_nameservers_and_suspend( evdns_base *base);
ev_int evdns_base_resume( evdns_base *base);
ev_int evdns_base_nameserver_ip_add( evdns_base *base,  char *ip_as_string);
evdns_request *evdns_base_resolve_ipv4( evdns_base *base,  char *name, ev_int flags, evdns_callback_type callback, void *ptr);
evdns_request *evdns_base_resolve_ipv6( evdns_base *base,  char *name, ev_int flags, evdns_callback_type callback, void *ptr);
evdns_request *evdns_base_resolve_reverse( evdns_base *base,   in_addr*, ev_int flags, evdns_callback_type callback, void *ptr);
evdns_request *evdns_base_resolve_reverse_ipv6( evdns_base *base,   in6_addr *, ev_int flags, evdns_callback_type callback, void *ptr);
void evdns_cancel_request( evdns_base *base,  evdns_request *req);
ev_int evdns_base_set_option( evdns_base *base,  char *option,  char *val);
ev_int evdns_base_resolv_conf_parse( evdns_base *base, ev_int flags,  char * filename);
ev_int evdns_base_load_hosts( evdns_base *base,  char *hosts_fname);
version(Windows){
ev_int evdns_base_config_windows_nameservers(evdns_base *);
}
void evdns_base_search_clear( evdns_base *base);
void evdns_base_search_add( evdns_base *base,  char *domain);
void evdns_base_search_ndots_set( evdns_base *base,  ev_int ndots);
void evdns_set_log_fn(evdns_debug_log_fn_type fn);
void evdns_set_transaction_id_fn(ev_uint16_t function());
void evdns_set_random_bytes_fn(void (*fn)(char *, size_t));
 evdns_server_port *evdns_add_server_port_with_base( event_base *base, evutil_socket_t socket, ev_int is_tcp, evdns_request_callback_fn_type callback, void *user_data);
void evdns_close_server_port( evdns_server_port *port);
void evdns_server_request_set_flags( evdns_server_request *req, ev_int flags);
ev_int evdns_server_request_add_reply( evdns_server_request *req, ev_int section,  char *name, ev_int type, ev_int dns_class, ev_int ttl, ev_int datalen, ev_int is_name,  char *data);
ev_int evdns_server_request_add_a_reply( evdns_server_request *req,  char *name, ev_int n, void *addrs, ev_int ttl);
ev_int evdns_server_request_add_aaaa_reply( evdns_server_request *req,  char *name, ev_int n, void *addrs, ev_int ttl);
ev_int evdns_server_request_add_ptr_reply( evdns_server_request *req,  in_addr*,  char *inaddr_name,  char *hostname, ev_int ttl);
ev_int evdns_server_request_add_cname_reply( evdns_server_request *req,  char *name,  char *cname, ev_int ttl);
ev_int evdns_server_request_respond( evdns_server_request *req, ev_int err);
ev_int evdns_server_request_drop( evdns_server_request *req);
ev_int evdns_server_request_get_requesting_addr( evdns_server_request *_req,  sockaddr *sa, ev_int addr_len);
evdns_getaddrinfo_request *evdns_getaddrinfo(evdns_base *dns_base,  char *nodename, char *servname, evutil_addrinfo *hints_in, evdns_getaddrinfo_cb cb, void *arg);
void evdns_getaddrinfo_cancel(evdns_getaddrinfo_request *req);

/* compat */
ev_int evdns_init();
 evdns_base *evdns_get_global_base();
void evdns_shutdown(ev_int fail_requests);
ev_int evdns_nameserver_add(ev_uint address);
ev_int evdns_count_nameservers();
ev_int evdns_clear_nameservers_and_suspend();
ev_int evdns_resume();
ev_int evdns_nameserver_ip_add( char *ip_as_string);
ev_int evdns_resolve_ipv4( char *name, ev_int flags, evdns_callback_type callback, void *ptr);
ev_int evdns_resolve_ipv6( char *name, ev_int flags, evdns_callback_type callback, void *ptr);
ev_int evdns_resolve_reverse(in_addr *, ev_int flags, evdns_callback_type callback, void *ptr);
ev_int evdns_resolve_reverse_ipv6(in6_addr*, ev_int flags, evdns_callback_type callback, void *ptr);
ev_int evdns_set_option( char *option,  char *val, ev_int flags);
ev_int evdns_resolv_conf_parse(ev_int flags,  char * filename);
void evdns_search_clear();
void evdns_search_add( char *domain);
void evdns_search_ndots_set( ev_int ndots);
evdns_server_port *evdns_add_server_port(evutil_socket_t socket, ev_int is_tcp, evdns_request_callback_fn_type callback, void *user_data);
version(Windows){
ev_int evdns_config_windows_nameservers();
}